var createError = require('http-errors');
var express = require('express');
var path = require('path');
var cookieParser = require('cookie-parser');
var bodyParser = require('body-parser');
var multer  = require('multer')
var logger = require('morgan');
var basicAuth = require('express-basic-auth')
var cors = require('cors')


var indexRouter = require('./routes/index');
var usersRouter = require('./routes/users');

var app = express();

// view engine setup
app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'ejs');

// 路由配置
app.set('strict routing', true) // 精确匹配
app.set('case sensitive routing', true) // 区分大小写

app.use(logger('dev'));

// app.use(express.json());
// app.use(express.urlencoded({ extended: false }));

app.use(bodyParser.text());
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: false }));

app.use(cookieParser());
app.use(express.static(path.join(__dirname, 'public')));

/********************** multipart/form-data  **********************/
/*
  Multer 接受一个 options 对象，其中最基本的是 dest 属性，
  这将告诉 Multer 将上传文件保存在哪。如果你省略 options对象，
  这些文件将保存在内存中，永远不会写入磁盘。
*/
// var upload = multer({ dest: 'uploads/' })

// 内存存储
// var storage = multer.memoryStorage()

// 磁盘存储
var storage = multer.diskStorage({
  destination: function (req, file, cb) {
    cb(null, 'uploads')
  },
  filename: function (req, file, cb) {
    cb(null, file.originalname + '-' + Date.now())
  }
})

var upload = multer({ storage: storage })

/********************** multipart/form-data  **********************/

app.use('/', indexRouter)
app.use('/users', usersRouter)

// /:id 动态路由的写法， id 在 req.params 中
app.get('/txt/:id',function (req,res) {
  console.log('req.body', req.body)
  setTimeout(() => {
    res.send({
      query: req.query,
      params: req.params,
      body: req.body
    });
  }, 5000)
})

app.post('/json', function (req,res) {
  console.log(req.body)
  res.setHeader('Set-Cookie', 'foo=bar; path=/');
  res.send({
    query: req.query,
    params: req.params,
    body: req.body
  });
})

app.post('/urlencoded',function (req,res) {
  console.log('body', req.body)
  res.send({
    query: req.query,
    params: req.params,
    body: req.body
  });
})

app.post('/upload', upload.any(), function (req,res) {
  console.log('req.files', req.files)
  res.send({
    query: req.query,
    params: req.params,
    body: req.body
  })
})

app.post('/download',function (req,res) {
  // 以下方法都会自动设置 Content-Type: text/plain; charset=UTF-8

  // 方式1
  // res.sendFile(path.join(__dirname, 'public/download.txt'))

  // 方式2
  // res.sendFile('download.txt', {
  //   root: path.join(__dirname, 'public'),
  //   dotfiles: 'deny',
  //   headers: {
  //     'x-timestamp': Date.now(),
  //     'x-sent': true
  //   }
  // }) 

  // 方式3
  // 手动调用 res.res.attachment 设置 Content-Disposition: attachment; filename="download.txt"，以附件的形式发送文件，浏览器会提示用户下载
  // res.attachment('download.txt') 
  // res.sendFile(path.join(__dirname, 'public/download.txt'))

  // 方式4
  // 自动设置 Content-Disposition: attachment; filename="download.txt"，以附件的形式发送文件，浏览器会提示用户下载
  // res.download(path.join(__dirname, 'public/download.txt'))

  res.download(path.join(__dirname, 'public/download.txt'))
})

app.post('/auth', basicAuth({
  challenge: true,
  users: { 'admin': '123456' }
}), function (req,res) {
  res.send({
    query: req.query,
    params: req.params,
    body: req.body
  });
})

app.get('/html', function(req,res) {
  res.send('<p style="color: red">Hello World</p>')
})

 app.get('/download',function (req,res) {
   res.download('public/download.txt');
 })

app.get('/redirect',function (req,res) {
  res.redirect('http://www.baidu.com')
})


// catch 404 and forward to error handler
app.use(function(req, res, next) {
  next(createError(404));
});

// error handler
app.use(function(err, req, res, next) {
  // set locals, only providing error in development
  res.locals.message = err.message;
  res.locals.error = req.app.get('env') === 'development' ? err : {};

  // render the error page
  res.status(err.status || 500);
  res.render('error');
});

module.exports = app;
